"""
区域选择器 - 提供类似截图软件的区域框选功能
"""

import sys
from PyQt5.QtWidgets import (QApplication, QWidget, QLabel, QVBoxLayout, 
                            QHBoxLayout, QPushButton, QDesktopWidget)
from PyQt5.QtCore import Qt, QRect, pyqtSignal, QTimer
from PyQt5.QtGui import QPainter, QPen, QColor, QPixmap, QFont
from PIL import ImageGrab
import logging


class AreaSelector(QWidget):
    """区域选择器窗口"""
    
    # 信号定义
    area_selected = pyqtSignal(tuple)  # 区域选择完成信号
    selection_cancelled = pyqtSignal()  # 选择取消信号
    
    def __init__(self):
        super().__init__()
        self.logger = logging.getLogger(__name__)
        
        # 选择状态
        self.selecting = False
        self.start_point = None
        self.end_point = None
        self.selection_rect = QRect()
        
        self.setup_ui()
    
    def setup_ui(self):
        """初始化UI"""
        # 设置窗口为全屏覆盖
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        
        # 获取屏幕尺寸并全屏显示
        desktop = QDesktopWidget()
        screen_rect = desktop.screenGeometry()
        self.setGeometry(screen_rect)
        
        # 设置鼠标跟踪
        self.setMouseTracking(True)
        
        # 设置光标
        self.setCursor(Qt.CrossCursor)
        
        self.logger.info("区域选择器界面初始化完成")
    
    def mousePressEvent(self, event):
        """鼠标按下事件"""
        if event.button() == Qt.LeftButton:
            self.selecting = True
            self.start_point = event.pos()
            self.end_point = event.pos()
            self.logger.debug(f"开始选择区域: {self.start_point}")
    
    def mouseMoveEvent(self, event):
        """鼠标移动事件"""
        if self.selecting:
            self.end_point = event.pos()
            self.update_selection()
            self.update()  # 触发重绘
    
    def mouseReleaseEvent(self, event):
        """鼠标释放事件"""
        if event.button() == Qt.LeftButton and self.selecting:
            self.selecting = False
            self.end_point = event.pos()
            self.finish_selection()
        elif event.button() == Qt.RightButton:
            # 右键取消选择
            self.cancel_selection()
    
    def keyPressEvent(self, event):
        """键盘事件"""
        if event.key() == Qt.Key_Escape:
            self.cancel_selection()
        else:
            super().keyPressEvent(event)
    
    def update_selection(self):
        """更新选择矩形"""
        if self.start_point and self.end_point:
            x1, y1 = self.start_point.x(), self.start_point.y()
            x2, y2 = self.end_point.x(), self.end_point.y()
            
            # 确保左上角为起始点
            left = min(x1, x2)
            top = min(y1, y2)
            width = abs(x2 - x1)
            height = abs(y2 - y1)
            
            self.selection_rect = QRect(left, top, width, height)
    
    def paintEvent(self, event):
        """绘制事件"""
        painter = QPainter(self)
        
        # 绘制半透明遮罩
        painter.fillRect(self.rect(), QColor(0, 0, 0, 100))
        
        # 如果有选择区域，绘制选择框
        if not self.selection_rect.isEmpty():
            # 清除选择区域的遮罩
            painter.setCompositionMode(QPainter.CompositionMode_Clear)
            painter.fillRect(self.selection_rect, Qt.transparent)
            
            # 绘制选择框边框
            painter.setCompositionMode(QPainter.CompositionMode_SourceOver)
            pen = QPen(QColor(0, 120, 215), 2)  # Windows蓝色边框
            painter.setPen(pen)
            painter.drawRect(self.selection_rect)
            
            # 绘制尺寸信息
            self.draw_size_info(painter)
    
    def draw_size_info(self, painter):
        """绘制尺寸信息"""
        if self.selection_rect.isEmpty():
            return
        
        width = self.selection_rect.width()
        height = self.selection_rect.height()
        
        # 设置字体
        font = QFont()
        font.setPointSize(12)
        painter.setFont(font)
        
        # 准备文本
        size_text = f"{width} × {height}"
        
        # 计算文本位置（选择框上方）
        text_rect = painter.fontMetrics().boundingRect(size_text)
        text_x = self.selection_rect.center().x() - text_rect.width() // 2
        text_y = self.selection_rect.top() - 10
        
        # 确保文本不超出屏幕
        if text_y < text_rect.height():
            text_y = self.selection_rect.bottom() + 20
        
        # 绘制文本背景
        bg_rect = QRect(text_x - 5, text_y - text_rect.height() - 2, 
                       text_rect.width() + 10, text_rect.height() + 4)
        painter.fillRect(bg_rect, QColor(0, 0, 0, 180))
        
        # 绘制文本
        painter.setPen(QColor(255, 255, 255))
        painter.drawText(text_x, text_y, size_text)
    
    def finish_selection(self):
        """完成选择"""
        if not self.selection_rect.isEmpty():
            # 获取选择区域坐标
            left = self.selection_rect.left()
            top = self.selection_rect.top()
            right = self.selection_rect.right()
            bottom = self.selection_rect.bottom()
            
            area_tuple = (left, top, right, bottom)
            
            self.logger.info(f"区域选择完成: {area_tuple}")
            self.area_selected.emit(area_tuple)
        else:
            self.logger.warning("未选择有效区域")
            self.cancel_selection()
        
        self.close()
    
    def cancel_selection(self):
        """取消选择"""
        self.logger.info("区域选择已取消")
        self.selection_cancelled.emit()
        self.close()


class AreaSelectorDialog:
    """区域选择对话框管理器"""
    
    def __init__(self):
        self.logger = logging.getLogger(__name__)
        self.selected_area = None
        self.cancelled = False
    
    def select_area(self) -> tuple:
        """
        启动区域选择
        Returns:
            选择的区域坐标 (left, top, right, bottom) 或 None
        """
        self.selected_area = None
        self.cancelled = False
        
        # 创建选择器
        selector = AreaSelector()
        
        # 连接信号
        selector.area_selected.connect(self.on_area_selected)
        selector.selection_cancelled.connect(self.on_selection_cancelled)
        
        # 显示选择器
        selector.show()
        
        self.logger.info("启动区域选择器")
        
        # 等待用户选择
        while selector.isVisible():
            QApplication.processEvents()
        
        if self.cancelled:
            return None
        
        return self.selected_area
    
    def on_area_selected(self, area):
        """区域选择完成回调"""
        self.selected_area = area
        self.logger.info(f"区域选择器返回: {area}")
    
    def on_selection_cancelled(self):
        """选择取消回调"""
        self.cancelled = True
        self.logger.info("区域选择器取消")


class AreaPreview(QLabel):
    """区域预览组件"""
    
    def __init__(self, parent=None):
        super().__init__(parent)
        self.logger = logging.getLogger(__name__)
        
        # 预览区域坐标
        self.preview_area = None
        
        # 设置样式
        self.setMinimumSize(200, 150)
        self.setStyleSheet("""
            QLabel {
                border: 2px dashed #ccc;
                background-color: #f9f9f9;
                color: #666;
                text-align: center;
            }
        """)
        self.setAlignment(Qt.AlignCenter)
        self.setText("点击框选区域\n预览将在此显示")
        
        # 定时器用于实时更新预览
        self.update_timer = QTimer()
        self.update_timer.timeout.connect(self.update_preview)
    
    def set_preview_area(self, area: tuple):
        """
        设置预览区域
        Args:
            area: 区域坐标 (left, top, right, bottom)
        """
        self.preview_area = area
        self.logger.info(f"设置预览区域: {area}")
        self.update_preview()
    
    def start_live_preview(self, interval: int = 1000):
        """
        启动实时预览
        Args:
            interval: 更新间隔（毫秒）
        """
        if self.preview_area:
            self.update_timer.start(interval)
            self.logger.info(f"启动实时预览，间隔: {interval}ms")
    
    def stop_live_preview(self):
        """停止实时预览"""
        self.update_timer.stop()
        self.logger.info("停止实时预览")
    
    def update_preview(self):
        """更新预览图片"""
        if not self.preview_area:
            return
        
        try:
            # 截取指定区域
            left, top, right, bottom = self.preview_area
            screenshot = ImageGrab.grab(bbox=self.preview_area)
            
            # 转换为QPixmap
            screenshot.save('temp_preview.png')
            pixmap = QPixmap('temp_preview.png')
            
            # 缩放以适应预览窗口
            scaled_pixmap = pixmap.scaled(
                self.size(), 
                Qt.KeepAspectRatio, 
                Qt.SmoothTransformation
            )
            
            # 显示预览图片
            self.setPixmap(scaled_pixmap)
            
            # 清理临时文件
            import os
            if os.path.exists('temp_preview.png'):
                os.remove('temp_preview.png')
        
        except Exception as e:
            self.logger.error(f"更新预览失败: {e}")
            self.setText("预览更新失败")
    
    def mousePressEvent(self, event):
        """点击预览区域重新选择"""
        if event.button() == Qt.LeftButton:
            # 启动区域选择
            dialog = AreaSelectorDialog()
            new_area = dialog.select_area()
            
            if new_area:
                self.set_preview_area(new_area)
                # 发送区域变更信号给父组件
                parent = self.parent()
                if parent and hasattr(parent, 'on_area_changed'):
                    parent.on_area_changed(new_area)
